<template>
<div class="tw-scroller"></div>
<!-- 用于测试 -->
  <!-- <div class="tw-scroller" style="position: relative !important;">
    <div v-for="n in 4" :key="n" style="height: 100vh; border: 5px solid #ccc;"></div>
  </div> -->
<!-- /用于测试 -->
</template>

<script>
import props from './props'
import style from '../tw-lib-base/style'
const TWEEN = require('@tweenjs/tween.js')

export default {
  name: 'lib-name',

  mixins: [style],

  props,

  data() {
    return {
      changeFromInside: false,
      pageNo: 0,
      prevPageYOffset: -1
    }
  },

  computed: {
    style () {
      return {
        scrollWidth: this.scrollWidth,
        scrollBg: this.scrollBg,
        scrollColor: this.scrollColor
      }
    }
  },

  methods: {
    setStyle () {
      if (this.styleEnable) {
        const style = `
          body::-webkit-scrollbar {
            width: ${this.scrollWidth};
            background-color: #f5f5f5;
          }

          body::-webkit-scrollbar-track {
            background-color: ${this.scrollBg};
          }

          body::-webkit-scrollbar-thumb {
            background-color: ${this.scrollColor};
          }
        `

        this.addStyle(style)
      }
    },

    preventWheel (e) {
      e.preventDefault()
    },

    handelEvent () {
      this.changeFromInside = true
      this.$emit('update:pageNum', this.pageNo)
      this.$emit('input', window.pageYOffset)
    },

    scrollToValue (pageNo, scrollTop) {
      window.removeEventListener('scroll', this.handleWindowScroll)

      function animate(time) {
        requestAnimationFrame(animate)
        TWEEN.update(time)
      }

      requestAnimationFrame(animate)

      const vm = this
      const coords = { y: window.pageYOffset }

      new TWEEN.Tween(coords)
        .to({ y: scrollTop || window.innerHeight * pageNo }, this.scrollTime || 300)
        .easing(TWEEN.Easing.Quadratic.Out)
        .onStart(() => {
          document.body.addEventListener('wheel', this.preventWheel, { passive: false })
        }).onUpdate(() => {
          window.scrollTo(0, coords.y)
        }).onComplete(() => {
          vm.prevPageYOffset = -1
          vm.handelEvent()
          window.removeEventListener('scroll', this.handleWindowScroll)
          window.addEventListener('scroll', this.handleWindowScroll)
          document.body.removeEventListener('wheel', this.preventWheel, { passive: false })
        }).start()
    },

    handleWindowScroll (event) {
      if (this.prevPageYOffset === -1) {
        this.prevPageYOffset = window.pageYOffset
        return
      }

      if (this.scrollScreen) {
        this.pageNo = Math.ceil(window.pageYOffset / window.innerHeight)

        if (!this.pages || this.pageNo <= this.pages) {
          if (window.pageYOffset > this.prevPageYOffset) {
            this.scrollToValue(this.pageNo)
          } else if (window.pageYOffset < this.prevPageYOffset) {
            this.pageNo = this.pageNo - 1
            this.scrollToValue(this.pageNo)
          }
        }
      }

      if (!this.lazing) {
        this.lazing = true
        this.handelEvent()

        setTimeout(() => {
          this.lazing = false
          this.handelEvent()
        }, 360)
      }

      this.prevPageYOffset = window.pageYOffset
    },

    scrollToPropValue () {
      if (this.changeFromInside) {
        this.changeFromInside = false
      } else {
        window.removeEventListener('scroll', this.handleWindowScroll)

        if (this.scrollScreen) {
          if (this.pageNum !== this.pageNo) {
            this.pageNo = this.pageNum
            this.scrollToValue(this.pageNo)
          } else {
            window.addEventListener('scroll', this.handleWindowScroll)
          }
        } else {
          const value = parseInt(this.value)

          if (value !== window.pageYOffset && value !== -1) {
            this.scrollToValue(0, value)
          } else {
            window.addEventListener('scroll', this.handleWindowScroll)
          }
        }
      }
    }
  },

  mounted () {
    this.scrollToPropValue()
  },

  beforeDestroy () {
    window.removeEventListener('scroll', this.handleWindowScroll)
  },

  watch: {
    value () {
      this.scrollToPropValue()
    },

    pageNum () {
      this.scrollToPropValue()
    }
  }
}
</script>

<style lang="scss">
  @import './css/index.scss';
</style>
